package com.state;

import com.state.face.State;
import com.state.impl.HasQuarterState;
import com.state.impl.NoQuarterState;
import com.state.impl.SoldOutState;
import com.state.impl.SoldState;
import com.state.impl.WinnerState;

/**
 * context类
 * 
 * @author Administrator
 * 
 */
public class GumballMachine {

	// 每个状态对修改关闭，让糖果机对扩展开放
	State soldOutState;
	State noQuarterState;
	State hasQuarterState;
	State soldState;
	State winnerState;

	// 初始状态
	State state = soldOutState;
	// 记录机器内有多少糖果
	int count = 0;

	public GumballMachine(int numberGumballs) {
		soldOutState = new SoldOutState(this);
		noQuarterState = new NoQuarterState(this);
		hasQuarterState = new HasQuarterState(this);
		soldState = new SoldState(this);
		winnerState = new WinnerState(this);

		this.count = numberGumballs;
		// 如果大于0个糖果，修改状态
		if (numberGumballs > 0) {
			state = noQuarterState;
		}
	}

	/**
	 * 现在这些动作变得很容易实现了，我们只是委托到当前状态
	 */
	public void insertQuarter() {
		state.insertQuarter();
	}

	/**
	 * 现在这些动作变得很容易实现了，我们只是委托到当前状态
	 */
	public void ejectQuarter() {
		state.ejectQuarter();
	}

	/**
	 * 现在这些动作变得很容易实现了，我们只是委托到当前状态
	 */
	public void turnCrank() {
		// 没有25分钱的时候转动曲柄也不会出糖果
		if (state.turnCrank()) {
			// 我们不需要准备dispense的动作方法，因为这只是一个内部动作，用户不可以直接要求机器发放糖果
			state.dispense();
		}
	}

	public void setState(State state) {
		this.state = state;
	}

	/**
	 * 辅助方法用于释放糖果，并将count实例变量的值减1
	 */
	public void releaseBall() {
		System.out.println("正在售出糖果...");
		if (count != 0) {
			count = count - 1;
		}
	}

	public int getCount() {
		return count;
	}

	public void refill(int count) {
		this.count = count;
		state = noQuarterState;
	}

	public State getState() {
		return state;
	}

	public State getSoldOutState() {
		return soldOutState;
	}

	public State getNoQuarterState() {
		return noQuarterState;
	}

	public State getHasQuarterState() {
		return hasQuarterState;
	}

	public State getSoldState() {
		return soldState;
	}

	public State getWinnerState() {
		return winnerState;
	}

	public String toString() {
		StringBuffer result = new StringBuffer();
		result.append("\nMighty Gumball, Inc.");
		result.append("\nJava-enabled Standing Gumball Model #2004");
		result.append("\nInventory: " + count + " gumball");
		if (count != 1) {
			result.append("s");
		}
		result.append("\n");
		result.append("Machine is " + state + "\n");
		return result.toString();
	}

}
